/*
 * Copyright 2009 IT Mill Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.opticon.vaadinR.ui;


import com.google.common.io.Files;
import com.opticon.vaadinR.core.conf.CoreConfiguration;
import com.opticon.vaadinR.core.log.StdOutErrLog;
import com.opticon.vaadinR.core.log.TextAreaAppender;
import com.opticon.vaadinR.core.r.ResultHandlerProvider;
import com.opticon.vaadinR.interfaces.RResultHandler;
import com.opticon.vaadinR.interfaces.VaadinRApplication;
import com.opticon.vaadinR.ui.demo.AbstractInputPanel;
import com.opticon.vaadinR.ui.demo.HuberInputPanel;
import com.opticon.vaadinR.ui.layout.GridPositionProvider;
import com.opticon.vaadinR.ui.panel.DashboardPanel;
import com.vaadin.Application;
import com.vaadin.terminal.gwt.server.WebApplicationContext;
import com.vaadin.ui.GridLayout;
import com.vaadin.ui.MenuBar;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.Window;
import org.apache.log4j.Logger;
import org.vaadin.sasha.portallayout.PortalLayout;

import javax.servlet.http.HttpSession;
import java.io.File;

/**
 * The Application's "main" class
 */
@SuppressWarnings("serial")
public class MyApplication extends Application implements VaadinRApplication {
    private static Logger logger = Logger.getLogger(MyApplication.class);

    public ResultHandlerProvider iResultHandlerProvider = new ResultHandlerProvider(this);

    private Window window;
    public File iTempDir;

    public String iSessionID;

    public TextArea iLoggerTextArea;
    public MenuBar iMenuBar;

    public AbstractInputPanel iInputPanel;
    private DashboardPanel iDashboardPanel;

    public void init() {
        logger.debug("opening new vaadinR session");
        StdOutErrLog.tieSystemOutAndErrToLog();

        CoreConfiguration.setApplication(this);
        // initiate the window
        window = new Window("vaadinR");

        setTheme("vaadinR");

        // Create a temporary folder for this application
        iTempDir = Files.createTempDir();

        initComponents();
        setMainWindow(window);

        parseSessionId();

        logger.debug("initialized VaadinRApplication");

    }


    private void parseSessionId() {
        WebApplicationContext ctx = null;
        HttpSession session = null;
        try {
            ctx = ((WebApplicationContext) getContext());
            session = ctx.getHttpSession();
        } catch (ClassCastException cce) {
            logger.error(cce.getMessage(), cce);
        }

        if (session != null) {
            iSessionID = session.getId();
        } else {
            iSessionID = "TIMESTAMP_ID_" + System.currentTimeMillis();
        }

    }

    /**
     * Initiate the main layout.
     */
    private void initComponents() {
        window.setCaption("vaadinR-web");

        iMenuBar = new MenuBar();
        window.addComponent(iMenuBar);

//        iInputPanel = new DensityInputPanel(this);
        iInputPanel = new HuberInputPanel(this);


        iLoggerTextArea = new TextArea();
        TextAreaAppender.setTextArea(iLoggerTextArea);
        iLoggerTextArea.setWidth("300px");
        iLoggerTextArea.setCaption("log");
        iLoggerTextArea.setValue("test on creation");

        iDashboardPanel = new DashboardPanel(this);
        RResultHandler lRResultHandler = getRResultHandlerProvider().getRHuberRResultHandler();
        lRResultHandler.setDashBoardManager(iDashboardPanel);

        final GridLayout lGridLayout = new GridLayout(4, 4);
        lGridLayout.setMargin(true);
        lGridLayout.setSizeFull();


        window.addComponent(lGridLayout);

        iMenuBar.addItem("show dashboard", buildPortletDashBoard(lGridLayout));
        iMenuBar.addItem("show options", buildPortletInput(lGridLayout));
        iMenuBar.addItem("show log", buildPortletLogger(lGridLayout));


        iMenuBar.addItem("make statement", new MenuBar.Command() {
            public void menuSelected(MenuBar.MenuItem selectedItem) {
                logger.debug("append new debug statement");
            }
        });
    }

    private MenuBar.Command buildPortletDashBoard(final GridLayout aGridLayout) {
        return new MenuBar.Command() {
            boolean hasBeenClicked = false;
            PortalLayout lDashBoardPortlet = new PortalLayout();

            public void menuSelected(MenuBar.MenuItem selectedItem) {
                if (hasBeenClicked == false) {
                    lDashBoardPortlet.addComponent(iDashboardPanel);
                    lDashBoardPortlet.setClosable(iDashboardPanel, false);

                    int[] lPositions = GridPositionProvider.getPositions(GridPositionProvider.COMPONENTS.DASHBOARD);
                    aGridLayout.addComponent(lDashBoardPortlet, lPositions[0], lPositions[1], lPositions[2], lPositions[3]);
                    aGridLayout.setSizeFull();
                    window.requestRepaintAll();
                    hasBeenClicked = true;
                } else {
                    lDashBoardPortlet.removeComponent(iDashboardPanel);
                    aGridLayout.removeComponent(lDashBoardPortlet);
                    aGridLayout.setSizeFull();
                    window.requestRepaintAll();
                    hasBeenClicked = false;
                }
            }
        };
    }


    private MenuBar.Command buildPortletLogger(final GridLayout aGridLayout) {
        return new MenuBar.Command() {
            boolean hasBeenClicked = false;
            PortalLayout lMessagePortlet = new PortalLayout();

            public void menuSelected(MenuBar.MenuItem selectedItem) {
                if (hasBeenClicked == false) {
                    lMessagePortlet.addComponent(iLoggerTextArea);
                    lMessagePortlet.setClosable(iLoggerTextArea, false);

                    int[] lPositions = GridPositionProvider.getPositions(GridPositionProvider.COMPONENTS.LOG);
                    aGridLayout.addComponent(lMessagePortlet, lPositions[0], lPositions[1], lPositions[2], lPositions[3]);

                    window.requestRepaintAll();
                    hasBeenClicked = true;
                } else {
                    lMessagePortlet.removeComponent(iLoggerTextArea);
                    aGridLayout.removeComponent(lMessagePortlet);
                    window.requestRepaintAll();
                    hasBeenClicked = false;
                }
            }
        };
    }

    private MenuBar.Command buildPortletInput(final GridLayout aGridLayout) {
        return new MenuBar.Command() {
            boolean hasBeenClicked = false;
            private PortalLayout lImportPortlet = new PortalLayout();

            public void menuSelected(MenuBar.MenuItem selectedItem) {
                if (!hasBeenClicked) {

                    lImportPortlet.setSizeFull();
                    lImportPortlet.addComponent(iInputPanel);
                    lImportPortlet.setClosable(iInputPanel, false);
                    int[] lPositions = GridPositionProvider.getPositions(GridPositionProvider.COMPONENTS.INPUT);
                    aGridLayout.addComponent(lImportPortlet, lPositions[0], lPositions[1], lPositions[2], lPositions[3]);

                    window.requestRepaintAll();

                    hasBeenClicked = true;
                } else {
                    lImportPortlet.removeComponent(iInputPanel);
                    aGridLayout.removeComponent(lImportPortlet);

                    window.requestRepaintAll();

                    hasBeenClicked = false;
                }

            }
        };
    }


    public String getSessionID() {
        return iSessionID;
    }

    public ResultHandlerProvider getRResultHandlerProvider() {
        return iResultHandlerProvider;
    }
}
